package hr.fer.zpr.nmbp.project3.dao;

import hr.fer.zpr.nmbp.project3.dao.exceptions.DAOException;
import hr.fer.zpr.nmbp.project3.dao.util.ObjectFromXMLGen;
import hr.fer.zpr.nmbp.project3.dao.util.XMLGen;
import hr.fer.zpr.nmbp.project3.model.Bolnica;

import java.util.ArrayList;
import java.util.List;

import org.exist.xmldb.XQueryService;
import org.w3c.dom.Node;
import org.xmldb.api.base.Collection;
import org.xmldb.api.base.ResourceIterator;
import org.xmldb.api.base.ResourceSet;
import org.xmldb.api.base.XMLDBException;
import org.xmldb.api.modules.XMLResource;

public class BolnicaDAO {
	
	private XQueryService xqs;
	
    public BolnicaDAO(Collection col) {
		try {
			this.xqs = (XQueryService)col.getService("XQueryService", "1.0");
		} catch (XMLDBException e) {
			throw new DAOException("Greška u radu s bazom");
		}
	}

	public void save(Bolnica bolnica) {		
    	try {
    		// Update bolnice ako postoji u bazi
			if(this.exists(bolnica)) {
				this.update(bolnica);
			}else{
		    	// Generiraj novu sifru ako ju nema
		    	if(bolnica.getSifra() == 0){
		    		bolnica.setSifra(this.generateNextSifra());
		    	}
	    	
		    	// Spremanje nove bolnice u bazu
				xqs.query("update insert " + XMLGen.getXML(bolnica) + "into /ebolnica/bolnice");
			}
		} catch (XMLDBException e) {
			throw new DAOException("Greška u radu s bazom!");
		}
    }
	
	private void update(Bolnica bolnica) throws XMLDBException{
    	// Ažuriranje bolnice
		xqs.query("update replace /ebolnica/bolnice/bolnica[@sifra=" + bolnica.getSifra() + "] with " + 
    		XMLGen.getXML(bolnica));
	}
    
    public void delete(Bolnica bolnica) {    	
    	
    	try {
    		// Brisanje stranih ključeva
    		xqs.query("update replace /ebolnica/lijecnici/lijecnik[@bolnica=" + bolnica.getSifra() + "]" +
    				"/@bolnica with 0");
    		// Brisanje bolnice
			xqs.query("update delete /ebolnica/bolnice/bolnica[@sifra=" + bolnica.getSifra() + "]");
		} catch (XMLDBException e) {
			throw new DAOException("Greška u radu s bazom!");
		}
    }

    /**
     * Samo gleda šifru.
     * @param bolnicaPrototype
     * @return 
     */
    public List<Bolnica> load(Bolnica bolnicaPrototype) {
    	List<Bolnica> allBolnice = this.loadAll();
    	List<Bolnica> filteredBolnice = new ArrayList<Bolnica>();
    	
    	for(Bolnica b : allBolnice){
    		if(b.getSifra() == bolnicaPrototype.getSifra()){
    			filteredBolnice.add(b);
    		}
    	}
    	
    	return filteredBolnice;
    }
    
    public List<Bolnica> loadAll() {
    	ArrayList<Bolnica> loadedBolnice = new ArrayList<Bolnica>();
    	
    	// Učitavanje bolnica
    	try {			
    		ResourceSet resSet = xqs.query("/ebolnica/bolnice/bolnica");
    		
    		ResourceIterator iter = resSet.getIterator();
			while(iter.hasMoreResources()){
				XMLResource res = (XMLResource) iter.nextResource();
				Bolnica tempBolnica = (Bolnica)ObjectFromXMLGen.createInstance(res.getContentAsDOM());
				if(tempBolnica != null){
					loadedBolnice.add(tempBolnica);
				}
			}
		} catch (XMLDBException e) {
			throw new DAOException("Greška u radu s bazom!");
		}
    	
    	return loadedBolnice;
    }

    private int generateNextSifra(){
    	int nextSifra;
    	
    	try {			
    		ResourceSet resSet = xqs.query("let $res := /ebolnica/bolnice/bolnica/@sifra return <nextid>{ " +
					"if (count($res) > 0) then max($res)+1 else 0+1 }</nextid>");
			Node node = (Node)((XMLResource)resSet.getIterator().nextResource()).getContentAsDOM();
			nextSifra = Integer.parseInt(node.getNodeValue());
		} catch (XMLDBException e) {
			throw new DAOException("Greška u radu s bazom!");
		}
    	
    	return nextSifra;
    }
    
    private boolean exists(Bolnica bolnica) throws XMLDBException{
    	
    	ResourceSet set = xqs.query("/ebolnica/bolnice/bolnica[@sifra="+bolnica.getSifra()+"]");
    	if(set.getSize() > 0){
    		return true;
    	}else{
    		return false;
    	}
    }
    
//    private void loadReferences(Bolnica bolnica){
//    	List<Lijecnik> lijecnici = new ArrayList<Lijecnik>();
//    	
//    	try {
//			
//			ResourceSet resSet = xqs.query("/ebolnica/lijecnici/lijecnik[@bolnica=" +
//					bolnica.getSifra() + "]");
//			
//			ResourceIterator iter = resSet.getIterator();
//			while(iter.hasMoreResources()){
//				XMLResource res = (XMLResource) iter.nextResource();
//				Lijecnik tempLijecnik = (Lijecnik)ObjectFromXMLGen.createInstance(res.getContentAsDOM());
//				if(tempLijecnik != null){
//					lijecnici.add(tempLijecnik);
//				}
//			}
//			
//			bolnica.setLijecnici(lijecnici);
//		} catch (XMLDBException e) {
//			throw new DAOException("Greška u radu s bazom!");
//		}
//    }
}
